﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using umbraco;
using umbraco.NodeFactory;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using System.Xml;

namespace ScDataTypes.DataTypes
{
    public abstract class BaseTreeviewControl : System.Web.UI.UpdatePanel
    {

        #region Variables

        TreeView _Nodes;
        ListBox _Selected;
        Button _Remove;
        Button _Up;
        Button _Down;

        Unit _ButtonWidth = new Unit("60px");

        public event MoveUpDelegate MoveUp;
        public event MoveDownDelegate MoveDown;
        public event RemoveDelegate Remove;
        public event SelectionChangedDelegate SelectionChanged;
        public delegate void MoveUpDelegate(object sender, EventArgs e);
        public delegate void MoveDownDelegate(object sender, EventArgs e);
        public delegate void RemoveDelegate(object sender, EventArgs e);
        public delegate void SelectionChangedDelegate(object sender, EventArgs e);

        #endregion

        #region Init and Constructor

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            this.EnsureChildControls();
        }

        #endregion

        #region Functions

        /// <summary>
        /// Convert object to int
        /// </summary>
        /// <param name="Value">Value to convert</param>
        /// <returns>Int representation of value</returns>
        public int ToInt(object Value)
        {
            try
            {
                if (!(Value is DBNull || Value == null))
                {
                    // Try and convert
                    int intValue;
                    if (int.TryParse(Value.ToString(), out intValue) == true)
                    {
                        return intValue;
                    }
                }
            }
            catch
            {
                // Error Handler
            }

            return 0;
        }

        /// <summary>
        /// Convert object to string
        /// </summary>
        /// <param name="Value">Value to convert</param>
        /// <returns>String representation of value</returns>
        public string ToStr(object Value)
        {
            try
            {
                if (!(Value is DBNull || Value == null))
                {
                    return Convert.ToString(Value);
                }
            }
            catch
            {
                // Error Handler
            }

            return string.Empty;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Base TreeView
        /// </summary>
        protected TreeView TreeView
        {
            get { return this._Nodes; }
        }

        /// <summary>
        /// Base ListBox
        /// </summary>
        protected ListBox ListBox
        {
            get { return this._Selected; }
        }
        
        #endregion

        #region Child Controls

        /// <summary>
        /// Create all child controls
        /// </summary>
        protected override void CreateChildControls()
        {
            // Add control to self
            this.ContentTemplateContainer.Controls.Add(this.CreateTableControls());

            // Event Handlers
            this._Nodes.SelectedNodeChanged += new EventHandler(_Nodes_SelectedNodeChanged);
            this._Nodes.TreeNodePopulate += new TreeNodeEventHandler(_Nodes_TreeNodePopulate);
            this._Remove.Click += new EventHandler(_Remove_Click);
            this._Up.Click += new EventHandler(_Up_Click); ;
            this._Down.Click += new EventHandler(_Down_Click);

            this.ChildControlsCreated();
        }
       
        /// <summary>
        /// Creates all controls and UI
        /// </summary>
        /// <returns>Table containing all controls</returns>
        Table CreateTableControls()
        {
            // Create controls
            this._Nodes = new TreeView();
            this._Nodes.Width = new Unit("280px");
            this._Nodes.Height = new Unit("150px");
            this._Nodes.ShowExpandCollapse = true;
            this._Nodes.EnableClientScript = true;
            this._Nodes.ExpandDepth = 1;

            this._Selected = new ListBox();
            this._Selected.Width = new Unit("200px");
            this._Selected.Height = new Unit("150px");

            this._Remove = new Button();
            this._Remove.Text = "Remove";
            this._Remove.Width = _ButtonWidth;

            this._Up = new Button();
            this._Up.Text = "Up";
            this._Up.Width = _ButtonWidth;

            this._Down = new Button();
            this._Down.Text = "Down";
            this._Down.Width = _ButtonWidth;

            // Crete table setup
            Table tblEditor = new Table();
            TableRow rowEditor = new TableRow();
            TableCell celNodes = new TableCell();
            TableCell celOptions = new TableCell();
            TableCell celSelected = new TableCell();
            TableCell celOrder = new TableCell();

            Panel pnlNodes = new Panel();
            pnlNodes.Style.Add("border", "1px solid #999");
            pnlNodes.Style.Add("width", new Unit("300px").ToString());
            pnlNodes.Style.Add("height", new Unit("150px").ToString());
            pnlNodes.Style.Add("overflow", "auto");
            pnlNodes.Style.Add("background-color", "white");

            celOptions.Width = new Unit("75px");
            celOptions.Style.Add("text-align", "center");

            celOrder.Width = new Unit("75px");
            celOrder.Style.Add("text-align", "center");
            celOrder.Style.Add("vertical-align", "top");

            tblEditor.CellPadding = 0;
            tblEditor.CellSpacing = 0;

            pnlNodes.Controls.Add(this._Nodes);
            celNodes.Controls.Add(pnlNodes);
            celOptions.Controls.Add(this._Remove);
            celSelected.Controls.Add(this._Selected);
            celOrder.Controls.Add(this._Up);
            celOrder.Controls.Add(this._Down);

            rowEditor.Cells.Add(celNodes);
            rowEditor.Cells.Add(celOptions);
            rowEditor.Cells.Add(celSelected);
            rowEditor.Cells.Add(celOrder);
            tblEditor.Rows.Add(rowEditor);

            return tblEditor;
        }

        /// <summary>
        /// Child controls created override
        /// </summary>
        protected virtual new void ChildControlsCreated()
        {
        }

        #endregion

        #region Postbacks

        void _Down_Click(object sender, EventArgs e)
        {
            // Check the node is not the bottom node
            if (this.ListBox.SelectedItem != null &&
                this.ListBox.SelectedIndex != this.ListBox.Items.Count - 1)
            {
                // Get the index of the node and a copy
                int intIndex = this.ListBox.SelectedIndex;
                ListItem objSelectedItem = this.ListBox.SelectedItem;

                // Remove the node and insert it below
                this.ListBox.Items.RemoveAt(intIndex);
                this.ListBox.Items.Insert(intIndex + 1, objSelectedItem);
            }

            if (this.MoveDown != null) this.MoveDown(this, new EventArgs());
        }

        void _Up_Click(object sender, EventArgs e)
        {
            // Check the node is not topmost
            if (this.ListBox.SelectedItem != null &&
                this.ListBox.SelectedIndex != 0)
            {
                // Get the index of the node and a copy
                int intIndex = this.ListBox.SelectedIndex;
                ListItem objSelectedItem = this.ListBox.SelectedItem;

                // Remove the node and insert it above
                this.ListBox.Items.RemoveAt(intIndex);
                this.ListBox.Items.Insert(intIndex - 1, objSelectedItem);
            }

            if (this.MoveUp != null) this.MoveUp(this, new EventArgs());
        }

        void _Remove_Click(object sender, EventArgs e)
        {
            // Check if a list item is selected
            if (this.ListBox.SelectedItem != null)
                this.ListBox.Items.RemoveAt(this.ListBox.SelectedIndex);

            if (this.Remove != null) this.Remove(this, new EventArgs());
        }

        void _Nodes_TreeNodePopulate(object sender, TreeNodeEventArgs e)
        {
            this.PopulateTreeView(e);
        }

        void _Nodes_SelectedNodeChanged(object sender, EventArgs e)
        {
            if (this.SelectionChanged != null) this.SelectionChanged(this, new EventArgs());
        }
                
        #endregion

        #region Treeview Details

        protected virtual void PopulateTreeView(TreeNodeEventArgs e)
        {
        }

        #endregion

    }
}
